var globals =
{
    /**
     * Function to set "handler" for list of objects
     * Handlers are given in format:
     * {
     *      idOfElement : { fn : functionToUse, scope: scopeToUse }
     *      ,anotherElement : {fn : ... }
     *      , ...
     * }
     * @param string identificatior ID of the calling instans
     * @param object handlers List of
     */
    bindHandlers : function (identificatior, handlers)
    {
        for(itemId in handlers)
        {
            if(handlers[itemId].item)
                item = handlers[itemId].item;
            else
                item = Ext.getCmp(itemId);
            if(item && typeof item.setHandler === 'function')
            {
                var functionToCall = handlers[itemId].fn, scopeToUse = handlers[itemId].scope;
                item.setHandler(functionToCall, scopeToUse);
            }
            else
            {
                sweatShop.log(identificatior+' missing item or setHandler() for id: '+itemId);
            }
        }
    }

    /**
     * Function to set "listener" for list of "events" for list of objects
     * Handlers are given in format:
     * {
     *      elementId : { item:ComponentToBind, event:'nameOfEvent', fn:functionToUse, scope:scopeToUse }
     *      orUniqueIndex : { item:ComponentToBind, event:'nameOfEvent', fn:functionToUse, scope:scopeToUse }
     *      , ...
     * }
     * @param string identificatior ID of the calling instanse
     * @param object handlers List of
     */

    , bindListeners : function (identificatior, handlers)
    {
        for(itemId in handlers)
        {
            if(handlers[itemId].item)
                item = handlers[itemId].item;
            else
                item = Ext.getCmp(itemId);
            if(item)
            {
                var eventName = handlers[itemId].event
                    , functionToCall = handlers[itemId].fn
                    , scopeToUse = handlers[itemId].scope;
                    
                if(item.on)
                    item.on(eventName, functionToCall, scopeToUse);
                else if(item.addListener)
                    item.addListener(eventName, functionToCall, scopeToUse);
                else
                    sweatShop.log(identificatior+' missing on() or addListener() for : '+itemId);
            }
            else
            {
                sweatShop.log(identificatior+' missing item for id: '+itemId);
            }
        }
    }
    /**
     * Common AJAX-listener for failed form submits
     */
    , formSubmitFailed : function (form, action)
    {
        switch (action.failureType) {
            case Ext.form.Action.CLIENT_INVALID:
                Ext.MessageBox.alert("Client failure", "Form may not be submitted with invalid field values");
                sweatShop.log("Client failure: Form may not be submitted with invalid field values", 2);
                break;
            case Ext.form.Action.CONNECT_FAILURE:
                Ext.MessageBox.alert("Network failure", "Unable to reach remote server");
                sweatShop.log("Network failure: Unable to reach remote server", 4);
                break;
            case Ext.form.Action.SERVER_INVALID:
                Ext.MessageBox.alert('Backend error', action.result.message);
                sweatShop.log("Backend error: "+action.result.message, 4);
        }
    }
    , proxyResultListener : function(DataProxy, action, data, response)
    {
       console.log(DataProxy, action, data, response);
       Ext.MessageBox.alert(
            response.raw.success ? 'Ok' : 'Error'
            , response.raw.message
        );
       sweatShop.log(response.raw.message, response.raw.success ? 1 : 3);
    }

    /**
     * Global function for logging GRUD stores write-actions result
     */
    , storeWriteListener : function(store,action,result,transaction,record)
    {
        console.log(result);
    }
    ,createEmptyRecordToGrid : function(grid, defaultValues)
	{
		var MetaRecord = grid.getStore().recordType
			, fieldlist = grid.getStore().reader.meta.fields
			, preset = defaultValues ? defaultValues:{};

		var rec = {};
		for(var x in fieldlist)
		{
            if(typeof fieldlist[x] != 'string') continue;
            i = fieldlist[x]
            rec[i] = preset[i] ? preset[i] : null;
		}
		var p = new MetaRecord(rec);
		grid.getStore().insert(0, p);
	}
	, setStoreWriter : function(store)
	{
		store.writer =  new Ext.data.JsonWriter({
			writeAllFields: true
			,meta : store.reader.meta
			,listful: true
		});
	}
	, reloadStoreAfterSuccessSubmit : function(store)
	{
		return function(form, action)
		{
			ppFunctions.log(action.result.message, 1);
			store.reload();
		}
	}
    , clearEmptyTexts : function (form, action)
    {
        console.log(form, action);
    }
};

sessionHandling = {
    userId : null
	,checkSession : function()
	{
		Ext.Ajax.request({
			url:'main/checkSession',
			callback: function (options, success, response) {
				var result = Ext.util.JSON.decode(response.responseText);
				if (result.success == false) {
					sessionHandling.showMask();
					sessionHandling.login();
                    sweatShop.log(result.message, 1);
				}
				else
                {
                    sessionHandling.hideMask();
                    sweatShop.log(result.message, 0);
                    sweatShop.session.userId = result.userId;
                    Ext.getCmp('scrumboardPanel').reloadAllTickets();
                    Ext.getCmp('backlogPanel').reloadAllTickets();
                }
					
			}
		});
	}
	,
	logout : function()
	{
		Ext.Ajax.request({
			url:'main/logout',
			callback: function (options, success, response) {
				var result = Ext.util.JSON.decode(response.responseText);
				if (result.success == false) {
					Ext.MessageBox.alert('Error', result.message);
                    sweatShop.log(result.message, 4);
				}else{
                    sweatShop.log(result.message, 1);
                    window.location = result.redirUrl;
				}
			}
		});

	}
	,
	login : function()
	{
		sessionHandling.loginWindow.show();
	}
	,
	loginHandler: function(form, action){
		if(action.failureType !== 'server' && typeof action.failureType !== 'undefined'){
			Ext.MessageBox.alert('Error', action.failureType);
		}else{
			if(action.result.success){
				Ext.getCmp('loginWindow').close();
				sessionHandling.hideMask();
                sweatShop.log(action.result.message, 1);
                sessionHandling.userId = action.result.userId;
			}else{
				Ext.MessageBox.alert('Error', action.result.message);
                sweatShop.log(action.result.message, 4);
			}
		}
	}
	,
	loginWindow : new Ext.Window({
		id: 'loginWindow',
		title: 'Login',
		//renderTo: 'loginWindowContainer',
		layout: 'form',
		width: 350,
		autoHeight: true,
		plain: true,
		closable: false,
		items:[
		theForm = new Ext.FormPanel({
			labelAlign: 'left',
			monitorValid: true,
			bodyStyle:'padding:5px',
			buttonAlign: 'center',
			labelWidth: 110,
			items: [{
				allowBlank: false,
				xtype:'textfield',
				fieldLabel: 'Username',
				name: 'username',
				maxLength: 50,
				width: 150,
				maskRe: /^[0-9a-zA-Z_.@]$/
			},{
				allowBlank: false,
				xtype:'textfield',
				inputType: 'password',
				name: 'password',
				fieldLabel: 'Password',
				width: 150
			}]
			,
			buttons: [loginButton = new Ext.Button({
				text: 'Login',
				formBind: true,
				handler: function(){
					theForm.form.submit({
						url:'main/login',
						waitMsg: 'Logging in...',
						success: sessionHandling.loginHandler,
						failure: sessionHandling.loginHandler
					});
				}
			})]
			,
			keys: [{
				key: [10, 13],
				fn: function() {
					loginButton.focus();
					loginButton.fireEvent("click", loginButton);
				}
			}]
		})
		]
	})
	,showMask : function()
	{
		Ext.get('loading').fadeIn();
		Ext.get('loading-mask').fadeIn();
	}
	,hideMask : function()
	{
		Ext.get('loading').fadeOut();
		Ext.get('loading-mask').fadeOut();
	}
};

sweatShop = {
    globals : globals
    , session : sessionHandling
    , viewPort : null
    , autoPromptHours : true
    , currentSprint : null
    , toggleAutoPromptHours : function (button, bool)
    {
        sweatShop.autoPromptHours = bool;
    }
    , log : function (message, gravity)
    {
        if(typeof gravity == 'undefined')
            gravity = 0;
        if(sweatShop.logContainer)
            Ext.getCmp('sweatshopLogPanel').addLogRow(message, gravity);
        if(typeof console != 'undefined')
            console.log(message);
        if(gravity == 1)
            sweatShop.msg('Info', message);
        if(gravity >= 2)
            sweatShop.alert(message);
    }
    , openTicketWizard : function()
    {
        win = Ext.getCmp('newTicketEditorWindow');
        if(!win)
            win = new newTicketEditor();
        win.show();
    }
    ,getFilters : function()
    {
        return {
            assignee : sweatShop.viewPort.northPanel.assigneeCombo.getValue()
            ,product : sweatShop.viewPort.northPanel.productCombo.getValue()
            ,sprint : sweatShop.viewPort.northPanel.sprintCombo.getValue()
        };
    }

    ,alert : function(message)
	{
		Ext.MessageBox.alert('Error', message);
	}
	,createBox : function(t, s){
        return ['<div class="msg">',
                '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>',
                '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc"><h3>', t, '</h3>', s, '</div></div></div>',
                '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>',
                '</div>'].join('');
    }
	,msg : function(title, message){
		msgCt = Ext.get('msg-div');
		if(!msgCt){
			msgCt = Ext.DomHelper.insertFirst(document.body, {id:'msg-div'}, true);
		}
		msgCt.alignTo(document, 't-t');

		var m = Ext.DomHelper.append(msgCt, {html:sweatShop.createBox(title, message)}, true);
		m.slideIn('t').pause(1).ghost("b", {remove:true});
	}
};